package com.woniuxy.yoga.coach.web.controller;


import cn.hutool.core.bean.BeanUtil;
import com.woniuxy.yoga.coach.dao.model.Coach;
import com.woniuxy.yoga.coach.model.dto.CoachDTO;
import com.woniuxy.yoga.coach.model.dto.CoachNameDTO;
import com.woniuxy.yoga.coach.model.exception.CoachException;
import com.woniuxy.yoga.coach.model.exception.CoachExceptionCode;
import com.woniuxy.yoga.coach.model.form.*;
import com.woniuxy.yoga.coach.model.param.*;
import com.woniuxy.yoga.coach.service.permission.Permission;
import com.woniuxy.yoga.coach.service.service.CoachService;
import com.woniuxy.yoga.commons.core.model.PageInfo;
import com.woniuxy.yoga.commons.core.model.Result;
import com.woniuxy.yoga.commons.core.util.FileUtil;
import com.woniuxy.yoga.commons.core.util.JWTUtil;
import com.woniuxy.yoga.commons.oss.util.OSSUtil;
import com.woniuxy.yoga.commons.redis.util.RedisUtil;
import com.woniuxy.yoga.commons.web.log.YogaLog;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.hibernate.validator.constraints.Length;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

/**
 * <p>
 * 教练表 前端控制器
 * </p>
 *
 * @author 韦用文,刘存益,郎腾霄
 * @since 2023年11月28日
 */
@RestController
@RequestMapping("/coach")
@Api(tags = "教练服务相关接口")
@Validated
public class CoachController {

    @Autowired
    private OSSUtil ossUtil;

    @Autowired
    private CoachService coachService;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 上传文件
     * @param image
     * @return
     * @throws IOException
     */
    @PostMapping("/upload.bu")
    @ApiOperation("上传文件接口")
//    @ApiImplicitParam(name = "image",value = "图片信息")
    public Result<String> uploadBookImage(MultipartFile image) throws IOException {
        //1.取出image中的文件内容
        InputStream inputStream = image.getInputStream();
        byte[] header = new byte[8];
        inputStream.read(header,0,8);
        //2.判断该文件的类型是否是图片
        if (!(FileUtil.isJpg(header)||FileUtil.isPng(header))){
            throw new CoachException(CoachExceptionCode.COACH_EXCEPTION_CODE_FORMAT_ERROR);
        }
        //3.生成新的图片名称
        String s = UUID.randomUUID().toString().replaceAll("-", "");
        String path = s + "." + (FileUtil.isJpg(header)?"jpg":"png");
        //4.调用API上传
        String newPath = ossUtil.uploadFile(image.getInputStream(), path);
        return Result.getResult(String.class).setMessage("上传图片成功").setData(newPath);
    }

    /**
     * 新增教练
     * @param addCoachForm
     * @return
     */
    @PostMapping("/addCoach.bu")
    @ApiOperation("新增教练接口")
    public Result<?> addCoach(@Valid @RequestBody AddCoachForm addCoachForm) throws Exception{
        coachService.addCoach(BeanUtil.toBean(addCoachForm, AddCoachParam.class));
        return Result.getResult().setMessage("新增教练成功");
    }

    /**
     * 判断账号是否存在
     * @param coachPhone
     * @return
     */
    @GetMapping("/checkPhone/{coachPhone}.co")
    @ApiOperation("判断账号是否存在接口")
    @ApiImplicitParam(name = "coachPhone",value = "联系方式")
    public Result<Boolean> checkPhone(@Valid @Pattern(regexp = "1[3-9]\\d{9}",message = "联系方式格式错误") @PathVariable("coachPhone") String coachPhone){
        Boolean exist = coachService.checkPhone(coachPhone);
        return Result.getResult(Boolean.class).setMessage("判断账号是否存在成功").setData(exist);
    }

    /**
     * 密码登录
     * @param passLoginForm
     * @return
     */
    @PostMapping("/passLogin.co")
    @ApiOperation("密码登录接口")
    @YogaLog("教练密码登录")
    public Result<CoachDTO> passLogin(@Valid @RequestBody PassLoginForm passLoginForm, HttpServletResponse response){
        CoachDTO coachDTO = coachService.passLogin(BeanUtil.toBean(passLoginForm, PassLoginParam.class));
        //生成令牌
        HashMap<String, Object> map = new HashMap<>();
        map.put("coachId",coachDTO.getCoachId());
        map.put("roleName","教练");
        //生成短token
        String accessToken = JWTUtil.createCoachToken(map, 30);
        //生成长token
        String refreshToken = JWTUtil.createCoachToken(map, 3 * 24 * 60);
        //将短token保存在请求头中
        response.setHeader("authen_token",accessToken);
        //将短token作为键 长token作为值 保存到Redis中
        redisUtil.set(accessToken,refreshToken,7*24*60*60L);
        //将token暴露给前端
        response.setHeader("Access-Control-Expose-Headers","authen_token");
        return Result.getResult(CoachDTO.class).setMessage("登录成功").setData(coachDTO);
    }

    /**
     * 发送验证码
     * @param coachPhone
     * @return
     */
    @GetMapping("/sendLoginCode/{coachPhone}.co")
    @ApiOperation("发送验证码接口")
    @ApiImplicitParam(name = "coachPhone",value = "联系方式")
    @YogaLog("发送验证码")
    public Result<?> sendLoginCode(@Valid @Pattern(regexp = "1[3-9]\\d{9}",message = "联系方式格式错误") @PathVariable("coachPhone") String coachPhone){
        coachService.sendLoginCode(coachPhone);
        return Result.getResult().setMessage("验证码发送成功");
    }

    /**
     * 验证码登录
     * @param codeLoginForm
     * @return
     */
    @PostMapping("/codeLogin.co")
    @ApiOperation("验证码登录接口")
    @YogaLog("教练验证码登录")
    public Result<CoachDTO> codeLogin(@Valid @RequestBody CodeLoginForm codeLoginForm,HttpServletResponse response){
        CoachDTO coachDTO = coachService.codeLogin(BeanUtil.toBean(codeLoginForm, CodeLoginParam.class));
        //生成令牌
        HashMap<String, Object> map = new HashMap<>();
        map.put("coachId",coachDTO.getCoachId());
        map.put("roleName","教练");
        //生成短token
        String accessToken = JWTUtil.createCoachToken(map, 30);
        //生成长token
        String refreshToken = JWTUtil.createCoachToken(map, 3 * 24 * 60);
        //将短token保存在请求头中
        response.setHeader("authen_token",accessToken);
        //将短token作为键 长token作为值 保存到Redis中
        redisUtil.set(accessToken,refreshToken,7*24*60*60L);
        //将token暴露给前端
        response.setHeader("Access-Control-Expose-Headers","authen_token");
        return Result.getResult(CoachDTO.class).setMessage("登录成功").setData(coachDTO);
    }

    /**
     * 找回密码
     * @param findPassForm
     * @return
     */
    @PostMapping("/findPass.co")
    @ApiOperation("找回密码接口")
    public Result<?> findPass(@Valid @RequestBody FindPassForm findPassForm){
        coachService.findPass(BeanUtil.toBean(findPassForm, FindPassParam.class));
        return Result.getResult().setMessage("找回密码成功");
    }

    /**
     * 修改密码
     * @param modifyPassForm
     * @return
     */
    @PostMapping("/modifyPass.co")
    @ApiOperation("修改密码接口")
    @YogaLog("修改密码")
    public Result<?> modifyPass(@Valid @RequestBody ModifyPassForm modifyPassForm){
        coachService.modifyPass(BeanUtil.toBean(modifyPassForm, ModifyPassParam.class));
        return Result.getResult().setMessage("修改密码成功");
    }

    /**
     * 学员查询正常教练
     * @return
     */
    @PostMapping("/queryStoreNormalCoach.us")
    @ApiOperation("学员查询正常教练接口")
    public Result<PageInfo> queryStoreNormalCoach(@RequestBody QueryStoreNormalCoachForm queryStoreNormalCoachForm){
        PageInfo pageInfo = coachService.queryStoreNormalCoach(BeanUtil.toBean(queryStoreNormalCoachForm,QueryStoreNormalCoachParam.class));
        return Result.getResult(PageInfo.class).setMessage("查询正常教练信息成功").setData(pageInfo);
    }

    /**
     * 启用教练账号
     * @param modifyNormalForm
     * @return
     */
    @PostMapping("/modifyNormal.bu")
    @ApiOperation("启用教练账号接口")
    @YogaLog("启用教练账号")
    public Result<?> modifyNormal(@Valid @RequestBody ModifyNormalForm modifyNormalForm){
        coachService.modifyNormal(BeanUtil.toBean(modifyNormalForm,ModifyNormalParam.class));
        return Result.getResult().setMessage("启用教练账号成功");
    }

    /**
     * 禁用教练账号
     * @param modifyDisableForm
     * @return
     */
    @PostMapping("/modifyDisable.bu")
    @ApiOperation("禁用教练账号接口")
    @YogaLog("禁用教练账号")
    public Result<?> modifyDisable(@Valid @RequestBody ModifyDisableForm modifyDisableForm){
        coachService.modifyDisable(BeanUtil.toBean(modifyDisableForm,ModifyDisableParam.class));
        return Result.getResult().setMessage("禁用教练账号成功");
    }

    /**
     * 删除教练账号
     * @param modifyDeleteForm
     * @return
     */
    @PostMapping("/modifyDelete.bu")
    @ApiOperation("删除教练账号接口")
    @YogaLog("删除教练账号")
    public Result<?> modifyDelete(@Valid @RequestBody ModifyDeleteForm modifyDeleteForm){
        coachService.modifyDelete(BeanUtil.toBean(modifyDeleteForm,ModifyDeleteParam.class));
        return Result.getResult().setMessage("删除教练账号成功");
    }

    /**
     * 商家查询自己的教练
     * @param storeQueryNormalCoachForm
     * @return
     */
    @PostMapping("/storeQueryNormalCoach.bu")
    @ApiOperation("商家查询自己的教练接口")
    public Result<PageInfo> storeQueryAllCoach(@Valid @RequestBody StoreQueryNormalCoachForm storeQueryNormalCoachForm){
        PageInfo pageInfo = coachService.storeQueryAllCoach(BeanUtil.toBean(storeQueryNormalCoachForm,StoreQueryNormalCoachParam.class));
        return Result.getResult(PageInfo.class).setMessage("商家查询自己的教练信息成功").setData(pageInfo);
    }

    /**
     * 平台查询所有的教练
     * @param adminQueryAllCoachForm
     * @return
     */
    @PostMapping("/adminQueryAllCoach.api")
    @ApiOperation("平台查询所有的教练接口")
    @Permission(resources = {"/coach/coach/adminQueryAllCoach.api"})
    public Result<PageInfo> adminQueryAllCoach(@RequestBody AdminQueryAllCoachForm adminQueryAllCoachForm){
        PageInfo pageInfo = coachService.adminQueryAllCoach(BeanUtil.toBean(adminQueryAllCoachForm,AdminQueryAllCoachParam.class));
        return Result.getResult(PageInfo.class).setMessage("平台查询所有的教练信息成功").setData(pageInfo);
    }

    /**
     * 根据ID查询教练信息
     * @param coachId
     * @return
     */
    @GetMapping("/getById/{coachId}")
    @ApiOperation("根据ID查询教练信息接口")
    @ApiImplicitParam(name = "coachId",value = "教练ID")
    public Result<Coach> getById(@Valid @NotNull(message = "教练ID不能为空") @PathVariable("coachId") Integer coachId){
        Coach coach = coachService.getById(coachId);
        return Result.getResult(Coach.class).setMessage("根据ID查询教练信息成功").setData(coach);
    }

    /**
     * 退出登录
     * @param authenToken
     * @return
     */
    @GetMapping("/exitLogin.co")
    @ApiOperation("退出登录接口")
    public Result<?> exitLogin(@RequestHeader("authen_token") String authenToken){
        //删除redis中的key
        redisUtil.delete(authenToken);
        return Result.getResult().setMessage("退出登录");
    }

    /**
     * 批量删除教练
     * @param storeId
     * @return
     */
    @GetMapping("/removeCoach/{storeId}")
    @ApiOperation("批量删除教练接口")
    @ApiImplicitParam(name = "storeId",value = "门店ID")
    public Result<?> removeCoach(@Valid @NotNull(message = "门店ID不能为空") @PathVariable("storeId") Integer storeId){
        coachService.removeCoach(storeId);
        return Result.getResult().setMessage("批量删除教练成功");
    }

    /**
     * 商家查询正常教练的姓名
     * @param storeId
     * @return
     */
    @GetMapping("/queryCoachName/{storeId}.bu")
    @ApiOperation("商家查询正常教练的姓名接口")
    @ApiImplicitParam(name = "storeId",value = "门店ID")
    public Result<List<CoachNameDTO>> queryCoachName(@Valid @NotNull(message = "门店ID不能为空") @PathVariable("storeId") Integer storeId){
        List<CoachNameDTO> coachNameDTOS = coachService.queryCoachName(storeId);
        return Result.getListResult(CoachNameDTO.class).setMessage("商家查询正常教练的姓名成功").setData(coachNameDTOS);
    }

}